package com.yuji.aacar.core.mvvm.apptask;


import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <li>Package:com.ttp.core.mvvm.apptask</li>
 * <li>Author: lining</li>
 * <li>Date: 2017/2/23</li>
 * <li>Description: Task管理类，主要负责监视Task的运行时间，不论什么状态，如果到30S就关闭Task，丢出请求失败的处理</li>
 * /**
 */
public class TaskMonitor {

    private static TaskMonitor instance;
    private boolean isDogRunning = false;

    private int TASK_TIMEOUT = 30 * 1000; // 单位毫秒

    public static synchronized TaskMonitor getInstance() {
        synchronized (TaskMonitor.class) {
            if (instance == null) {
                instance = new TaskMonitor();
            }
            return instance;
        }
    }

    private ConcurrentHashMap<TaskToken, Long> taskTimers; //Task与对应运行时间的容器

    TaskMonitor() {
        taskTimers = new ConcurrentHashMap<>();
    }

    /**
     * 记录Task开始时间
     *
     * @param token
     */
    synchronized void addTask(TaskToken token) {
//        XLog.instance().log().debug("[TaskMonitor]: start monitor task [" + token.method + "]");
        taskTimers.put(token, System.currentTimeMillis());

        if (!isDogRunning) {
            isDogRunning = true;
            new Thread(new TaskWatchDog()).start();
        }
    }

    /**
     * 从Task时间备份容器清除Task
     *
     * @param token
     */
    synchronized void removeTask(TaskToken token) {
        if (taskTimers.containsKey(token)) {
            taskTimers.remove(token);
        }
    }

    class TaskWatchDog implements Runnable {

        @Override
        public void run() {

//            XLog.instance().log().debug("[TaskMonitor]: TaskWatchDog run");

            try {
                while (taskTimers.size() > 0) {

                    Thread.sleep(1000);
                    long curTime = System.currentTimeMillis();
                    Iterator iter = taskTimers.entrySet().iterator();
                    while (iter.hasNext()) {
                        Map.Entry entry = (Map.Entry) iter.next();
                        TaskToken token = (TaskToken) entry.getKey();
                        if (taskTimers.containsKey(token)) {
                            long time = taskTimers.get(token);

                            // 时间超过20s，做请求超时处理
                            if ((curTime - time) > TASK_TIMEOUT) {
//                                XLog.instance().log().debug("[TaskMonitor]:" + "TimeOut（20s）:" + token.method);
                                TaskManager.getInstance().stopTask(token);
                                removeTask(token);
                            }
                        }
                    }
                }

            } catch (InterruptedException e) {
//                XLog.instance().log().error("[TaskMonitor]: TaskWatchDog catch InterruptedException",e);
                e.printStackTrace();
            } catch (Exception ex) {
//                XLog.instance().log().error("[TaskMonitor]: TaskWatchDog catch Exception",ex);
                ex.printStackTrace();
            } finally {
                isDogRunning = false;
//                XLog.instance().log().debug("[TaskMonitor]: TaskWatchDog stop");
            }
        }
    }
}


